home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 2 / ETO Development Tools 2.iso / Tools - Objects / MacApp / MacApp CD Release / MacApp 2.0.1 (Many Libraries) / Interfaces / PInterfaces / UList.p < prev    next >
Encoding:
Text File  |  1990-10-25  |  22.9 KB  |  548 lines  |  [TEXT/MPS ]

  1. {[a-,body+,h-,o=100,r+,rec+,t=4,u+,#+,j=20/57/1$,n-]}
  2. { UList.p }
  3. { Copyright © 1984-1990 by Apple Computer Inc. All rights reserved. }
  4.  
  5. { Unit UList defines object types TList, a simple dynamic array whose elements are references to
  6.   TObjects, and TSortedList, which maintains the object references in a sequence defined by
  7.   overriding TSortedList.Compare.
  8.  
  9.     Peter Gaston's scheme for chunky memory allocation has been used by permission.
  10.     Thanks Peter!.
  11.  
  12. TList:
  13.     TList is an object which provides a very nice dynamic array of objects.
  14.     It is implemented by appending the dynamic array onto the end of the
  15.     object.  Growing and shrinking the array is done by growing and shrinking
  16.     the handle which holds the object.
  17.  
  18. TSortedList:
  19.     TSortedList maintains the object references in a sequence defined by
  20.     overriding TSortedList.Compare
  21.  
  22.  
  23. Some Specific uses that TList is especially good for.
  24.  
  25.     LIFO Stack:
  26.         A push/pop operation is provided.
  27.  
  28.     FIFO Stack: (Queue)
  29.         Use InsertLast for Queue and First for Dequeue.
  30.  
  31.     Pre-allocation of your list:
  32.         If you know the size that your list will eventually reach, then you can
  33.         pre-set it to the proper size.
  34.  
  35.     Delete by Index:
  36.         If you keep track of items by index number, then you can avoid
  37.         a linear search when you want to delete it. Remember though, it
  38.         is a dynamic list and any insertion/deletion activity can cause
  39.         the index to point at a different element than you expect.
  40.  
  41. Caveats:
  42.     A _small_ amount of memory is always wasted with this method.  An active
  43.     list will generally waste one-half of the chunk size, or
  44.     4*2=8 bytes/TList.
  45.  
  46. }
  47.  
  48. {$IFC UNDEFINED UsingIncludes}
  49. {$SETC UsingIncludes := FALSE}
  50. {$ENDC}
  51.  
  52. {$IFC NOT UsingIncludes}
  53. UNIT UList;
  54.  
  55.     INTERFACE
  56.         {$ENDC}
  57.  
  58.         {$IFC UNDEFINED __UList__}
  59.         {$SETC __UList__ := FALSE}
  60.         {$ENDC}
  61.  
  62.         {$IFC NOT __UList__}
  63.         {$SETC __UList__ := TRUE}
  64.  
  65.         { • Auto-Include the requirements for this unit's interface. }
  66.         {$SETC UListIncludes := UsingIncludes}
  67.         {$SETC UsingIncludes := TRUE}
  68.         {$I+}
  69.         {$IFC UNDEFINED __UObject__} {$I UObject.p} {$ENDC}
  70.         {$SETC UsingIncludes := UListIncludes}
  71.  
  72.         CONST
  73.             kAllocationIncrement = 6;                    { Initial Allocation increment. Six
  74.                                                          elements of slop shouldn't break anybody
  75.                                                          and provides a _nice_ cushion from the
  76.                                                          memory manager. }
  77.             kIterateForward     = true;
  78.             kIterateBackward    = NOT kIterateForward;
  79.  
  80.             kEmptyIndex         = 0;                    { Value to use when no valid index is
  81.                                                          available Indexes are always positive }
  82.  
  83.             { Constants for TSortedList.Compare }
  84.             kItem1LessThanItem2 = - 1;
  85.             kItem1EqualItem2    = 0;
  86.             kItem1GreaterThanItem2 = 1;
  87.  
  88.             kALessThanB         = kItem1LessThanItem2;    { Left in for compatibility (2.0) }
  89.             kAEqualB            = kItem1EqualItem2;     { Left in for compatibility (2.0) }
  90.             kAGreaterThanB        = kItem1GreaterThanItem2; { Left in for compatibility (2.0) }
  91.  
  92.             { Constants for TSortedList.Search.
  93.             The criteria is considered to be item 2}
  94.             kItemGreaterThanCriteria = kItem1LessThanItem2;
  95.             kItemEqualCriteria    = kItem1EqualItem2;
  96.             kItemLessThanCriteria = kItem1GreaterThanItem2;
  97.  
  98.         TYPE
  99.  
  100.             PtrBasedDoublyLinkedListNodePtr = ^PtrBasedDoublyLinkedListNode;
  101.             PtrBasedDoublyLinkedListNode = RECORD
  102.                 previousLink:        PtrBasedDoublyLinkedListNodePtr; { link to previous node }
  103.                 nextLink:            PtrBasedDoublyLinkedListNodePtr; { link to next node }
  104.                 END;
  105.  
  106.             TPtrBasedDoublyLinkedList = OBJECT (TObject) { Manages a doubly linked list of nodes.
  107.                                                           The nodes are pointer based since they
  108.                                                           will typically be on the stack }
  109.                 fHeadNodePtr:        PtrBasedDoublyLinkedListNodePtr; { HEAD of the linked list }
  110.                 fTailNodePtr:        PtrBasedDoublyLinkedListNodePtr; { TAIL of the linked list }
  111.                                 {Creation/Destruction Methods}
  112.  
  113.                 PROCEDURE TPtrBasedDoublyLinkedList.IPtrBasedDoublyLinkedList;
  114.                 { Initialize a new linked list.}
  115.  
  116.                 PROCEDURE TPtrBasedDoublyLinkedList.AppendNode(thisNode: UNIV
  117.                                                                PtrBasedDoublyLinkedListNodePtr);
  118.                 { Add a new node to the list }
  119.  
  120.                 PROCEDURE TPtrBasedDoublyLinkedList.RemoveNode(thisNode: UNIV
  121.                                                                PtrBasedDoublyLinkedListNodePtr);
  122.                 { Remove a node from the list }
  123.  
  124.                 PROCEDURE TPtrBasedDoublyLinkedList.EachNodeDo(PROCEDURE
  125.                                                                DoToNode(thisNode: UNIV
  126.                                                                      PtrBasedDoublyLinkedListNodePtr
  127.                                                                         ));
  128.                 { Call do to node for each node in the list, passing a pointer to the node as a
  129.                 parameter to the called procedure. }
  130.  
  131.                 { Debugging Methods }
  132.  
  133.                 PROCEDURE TPtrBasedDoublyLinkedList.Fields(PROCEDURE
  134.                                                            DoToField(fieldName: Str255;
  135.                                                                      fieldAddr: Ptr;
  136.                                                                      fieldType: integer)); OVERRIDE;
  137.                 { Used by the Inspector and the Debugger to display the contents of this class's
  138.                 fields. }
  139.  
  140.                 END;
  141.  
  142.             ArrayIndex            = kEmptyIndex..MaxLongint; { At least always positive ( in this
  143.                                                             universe ) !!! kEmptyIndex..MaxLong
  144.                                                             would be a nice enhancement }
  145.             CompareResult        = integer;                { Negative, zero, and positive results are
  146.                                                          all meaningful even though we have the
  147.                                                          nice constants above. }
  148.  
  149.  
  150.             IterationNodePtr    = ^IterationNode;
  151.             IterationNode        = RECORD
  152.                 previousLink:        IterationNodePtr;    { link to previous iteration record }
  153.                 nextLink:            IterationNodePtr;    { link to next iteration record }
  154.                 iterLowBound:        ArrayIndex;            { lower bound of iteration in progress }
  155.                 iterIndex:            ArrayIndex;         { current index of this iteration }
  156.                 iterHighBound:        ArrayIndex;            { upper bound of iteration in progress }
  157.                 iterForward:        Boolean;            { if iteration is forward or backward
  158.                                                          through the list }
  159.                 END;
  160.  
  161.             TDynamicArray        = OBJECT (TPtrBasedDoublyLinkedList) { TDynamicArrays don't really
  162.                                                                       have an IS A relationship
  163.                                                                       with
  164.                                                                       TPtrBasedDoublyLinkedList but
  165.                                                                       have a HAS A relationship
  166.                                                                       with it. We subclass it here,
  167.                                                                       however, because to have a
  168.                                                                       HAS A relationship with it
  169.                                                                       would require *YET ANOTHER*
  170.                                                                       object in the heap and this
  171.                                                                       dynamically sized object
  172.                                                                       stuff is supposed to help
  173.                                                                       reduce that need. }
  174.                 fSize:                ArrayIndex;         { number of elements ACTUALLY in the array,
  175.                                                          from 0 to the limit of memory}
  176.                 fElementSize:        integer;            { Size in bytes of an element. MUST be a
  177.                                                          power of 2 ie. 1, 2, 4, 8, 16, etc. }
  178.                 fElementSizeShift:    integer;            { the power of 2 for the element size. Will
  179.                                                          be used to avoid DIV and MUL }
  180.  
  181.                 fAllocationIncrement: ArrayIndex;        { Number of elements by which to increase of
  182.                                                          decrease the allocated size of the array
  183.                                                          when it needs to grow or shrink. Thus
  184.                                                          reducing memory manager aggravation. }
  185.                 fAllocatedSize:     ArrayIndex;         { Number of elements for which storage is
  186.                                                          ALLOCATED }
  187.                 fFreeRequested:     Boolean;            { TRUE if the Free method was called but
  188.                                                          couldn't be honored because enumeration
  189.                                                          was in process. Checked at end of
  190.                                                          enumeration and Free is called if true }
  191.                 fClassSize:            Size;                { Used with ComputeAddress to create a
  192.                                                         pointer to an element.  This breaks
  193.                                                         encapsulation of GetDynamicArea but, is being
  194.                                                         done here for performance reasons (small) }
  195.                                 {Creation/Destruction Methods}
  196.  
  197.                 PROCEDURE TDynamicArray.IDynamicArray(initialSize: ArrayIndex;
  198.                                                       elementSize: integer);
  199.                 { Initialize a new array with initialSize elements, Always call it once before
  200.                 calling any other method.  Never call it twice.}
  201.  
  202.                 { Array manipulation primitives }
  203.  
  204.                 FUNCTION TDynamicArray.GetSize: ArrayIndex;
  205.                 { Returns the ACTUAL number of elements in the array.}
  206.  
  207.                 PROCEDURE TDynamicArray.SetArraySize(theSize: ArrayIndex);
  208.                 { Sets the array allocation to handle up to theSize elements }
  209.  
  210.                 FUNCTION TDynamicArray.EachElementDoTil(FUNCTION
  211.                                                         TestElement(elementIndex: ArrayIndex):
  212.                                                         Boolean;
  213.                                                         IterateForward: Boolean): ArrayIndex;
  214.                 { The basic array iterator. Call TestIndex once for each element of the array, in order,
  215.                 until TestIndex returns TRUE.
  216.                   Return the element that satisfied the test.  If none satisfied the test, return kEmptyIndex.
  217.                 }
  218.                 PROCEDURE TDynamicArray.Free; OVERRIDE;
  219.                 { If enumeration of the array is in process, delete all the array elements,
  220.                 mark the fFreeRequested flag for testing at completion of the enumeration and
  221.                 return.  Otherwise really free the array.  Gee, wouldn't automatic storage
  222.                 management be great! }
  223.  
  224.                 PROCEDURE TDynamicArray.InsertElementsBefore(index: ArrayIndex;
  225.                                                              ElementPtr: UNIV Ptr;
  226.                                                              count: ArrayIndex);
  227.                 { Insert Elements before the indicated Element. The index of the new element
  228.                   will be index.   If index = 1 this inserts at the start of the array. If index = fSize + 1
  229.                   this inserts at the end of the array. Signals Failure if unable to change the size of
  230.                   the array.
  231.  
  232.                   !!! NOTE MULTIPLE ( >1 ) element moves for non-power of 2 element sizes are NOT
  233.                   yet supported! }
  234.  
  235.                 PROCEDURE TDynamicArray.ReplaceElementsAt(index: ArrayIndex;
  236.                                                           ElementPtr: UNIV Ptr;
  237.                                                           count: ArrayIndex);
  238.                 { Replaces the Elements at the indicated index.
  239.  
  240.                   !!! NOTE MULTIPLE ( >1 ) element moves for non-power of 2 element sizes are NOT
  241.                   yet supported! }
  242.  
  243.                 PROCEDURE TDynamicArray.DeleteElementsAt(index: ArrayIndex;
  244.                                                          count: ArrayIndex);
  245.                 { Deletes the Element at the indicated index.  Compresses the array
  246.  
  247.                   !!! NOTE MULTIPLE ( >1 ) element moves for non-power of 2 element sizes are NOT
  248.                   yet supported! }
  249.  
  250.                 PROCEDURE TDynamicArray.GetElementsAt(index: ArrayIndex;
  251.                                                       ElementPtr: UNIV Ptr;
  252.                                                       count: ArrayIndex);
  253.                 { copies count elements to the location specified by ptr.
  254.  
  255.                   !!! NOTE MULTIPLE ( >1 ) element moves for non-power of 2 element sizes are NOT
  256.                   yet supported! }
  257.  
  258.                 FUNCTION TDynamicArray.ComputeAddress(index: ArrayIndex): Ptr;
  259.                 { Returns a pointer to of the index-th element in the array.
  260.  
  261.                 PLEASE NOTE: The return value is a direct heap pointer and should be used with
  262.                 care as the heap can compact across calls that move memory; thus invalidating
  263.                 the pointer. }
  264.  
  265.                 { Misc. functions }
  266.  
  267.                 FUNCTION TDynamicArray.IsEmpty: Boolean;
  268.                 { Test if this array is empty or not. }
  269.  
  270.                 PROCEDURE TDynamicArray.Merge(aDynamicArray: TDynamicArray);
  271.                 { merges aDynamicArray with itself. leaves aDynamicArray unchanged.
  272.  
  273.                   !!! NOTE MULTIPLE ( >1 ) element moves for non-power of 2 element sizes are NOT
  274.                   yet supported! }
  275.  
  276.                 { Debugging Methods }
  277.  
  278.                 PROCEDURE TDynamicArray.Fields(PROCEDURE
  279.                                                DoToField(fieldName: Str255;
  280.                                                          fieldAddr: Ptr;
  281.                                                          fieldType: integer)); OVERRIDE;
  282.                 { Used by the Inspector and the Debugger to display the contents of this class's
  283.                 fields. }
  284.  
  285.                 PROCEDURE TDynamicArray.DynamicFields(PROCEDURE
  286.                                                       DoToField(fieldName: Str255;
  287.                                                                 fieldAddr: Ptr;
  288.                                                                 fieldType: integer)); OVERRIDE;
  289.                 { Used by the Inspector and the Debugger to display the contents of this class's
  290.                 dynamic area. }
  291.  
  292.                 END;
  293.  
  294.             TList                = OBJECT (TDynamicArray) {A dynamic list of TObjects. It IS
  295.                                                           permissible for descendants to add more
  296.                                                           named fields}
  297.                 fObjClassID:        ObjClassID;         { if <> kNilClass then the Class ID of the
  298.                                                          elements of the list }
  299.                                 {Creation/Destruction Methods}
  300.  
  301.                 PROCEDURE TList.IList;
  302.                 { Initialize a new list with no elements, i.e., fSize = 0.    Always
  303.                   call it once before calling any other method.  Never call it
  304.                   twice.}
  305.  
  306.                 PROCEDURE TList.FreeList;
  307.                 { Frees each object in the list, then frees the list.}
  308.  
  309.                 { Utility Methods}
  310.  
  311.                 FUNCTION TList.At(index: ArrayIndex): TObject;
  312.                 { Return the index'th element of the list. It is typical for the caller to coerce the
  313.                 result into a descendant of TObject. All lists are indexed from 1. Range check only
  314.                 if the compile-flag qRangeCheck is TRUE. The static-array equivalent of:
  315.                 object := objList.At(index); is: object := objArray[index]; }
  316.  
  317.                 FUNCTION TList.GetEqualItemNo(item: TObject): ArrayIndex;
  318.                { Return the index of the item in the list, or zero if the item is not in the list. }
  319.  
  320.                 FUNCTION TList.GetSameItemNo(item: TObject): ArrayIndex;
  321.                 { Return the index of the IDENTITY item in the list, or zero if the item is not in the
  322.                 list. }
  323.  
  324.                 FUNCTION TList.First: TObject;
  325.                 { Return the first element of the list. It is typical for the caller to coerce the
  326.                 result. Returns NIL if the size is <= 0. }
  327.  
  328.                 FUNCTION TList.Last: TObject;
  329.                 { Return the last element of the list. It is typical for the caller to coerce the
  330.                 result. Returns NIL if the size is <= 0. }
  331.  
  332.                 {Iterator Methods}
  333.  
  334.                 FUNCTION TList.IterateTil(FUNCTION TestItem(item: TObject): Boolean;
  335.                                           IterateForward: Boolean;
  336.                                           VAR itsIndex: ArrayIndex): TObject;
  337.                 { The basic list iterator.    Call TestItem once for each element of the list, in order,
  338.                 until TestItem returns TRUE.
  339.                   Return the element that satisfied the test.  If none satisfied the test, return NIL.
  340.                   The actual parameter is typically a procedure whose argument is a descendant of TObject.
  341.                   It is typical for the caller to coerce the result into that descendant of TObject.
  342.                   If TestItem calls InsertLast, the newly added element will NOT be enumerated.
  343.                   If TestItem calls AtPut, InsertBefore, InsertFirst, or DeleteAll, misbehavior will
  344.                   ensue.  The static-array equivalent of:
  345.                     object := objList.FirstThat(Func)
  346.                   is:
  347.                     object := NIL;
  348.                     FOR index := 1 TO fSize DO IF Func(objArray[index]) THEN
  349.                         BEGIN
  350.                         object := objArray[index];
  351.                         LEAVE;
  352.                         END;
  353.                 }
  354.  
  355.                 PROCEDURE TList.Each(PROCEDURE DoToItem(item: TObject));
  356.                 { Call DoToItem once for each element of the list, in order. The actual parameter is
  357.                 typically a procedure whose argument is a descendant of TObject.
  358.                 The static-array equivalent of:
  359.                 objList.Each(Proc) is:
  360.                 FOR index := 1 TO fSize DO
  361.                     Proc(objArray[index]);
  362.                 }
  363.  
  364.                 FUNCTION TList.FirstThat(FUNCTION TestItem(item: TObject): Boolean): TObject;
  365.                 { Call TestItem once for each element of the list, in order, until TestItem returns
  366.                 TRUE. Return the element that satisfied the test. If none satisfied the test,
  367.                 return NIL. The actual parameter is typically a procedure whose argument is a
  368.                 descendant of TObject. It is typical for the caller to coerce the result into that
  369.                 descendant of TObject. If TestItem calls InsertLast, the newly added element will
  370.                 NOT be enumerated. If TestItem calls AtPut, InsertBefore, InsertFirst, Delete, or
  371.                 DeleteAll, misbehavior will ensue. }
  372.  
  373.                 FUNCTION TList.LastThat(FUNCTION TestItem(item: TObject): Boolean): TObject;
  374.                 { Call TestItem once for each element of the list, starting with the last item in the
  375.                 list and working toward the first item, until TestItem returns TRUE. Return the
  376.                 element that satisfied the test. If none satisfied the test, return NIL. The actual
  377.                 parameter is typically a procedure whose argument is a descendant of TObject. It is
  378.                 typical for the caller to coerce the result into that descendant of TObject. If
  379.                 TestItem calls InsertLast, the newly added element will NOT be enumerated. If
  380.                 TestItem calls AtPut, InsertBefore, InsertFirst, Delete, or DeleteAll, misbehavior
  381.                 will ensue. }
  382.  
  383.                 {Item Insertion Methods}
  384.  
  385.                 PROCEDURE TList.AtPut(index: ArrayIndex;
  386.                                       newItem: TObject);
  387.                 { Replace the index'th item of the list. Does not free the old item. If you do this
  388.                 from within an Each the results will be unpredictable.}
  389.  
  390.                 PROCEDURE TList.Insert(item: TObject);
  391.                 { Inserts the given item into the list in arrival sequence. }
  392.  
  393.                 PROCEDURE TList.InsertBefore(index: ArrayIndex;
  394.                                              item: TObject);
  395.                 { Insert a reference to an item before the indicated item. The index of the new
  396.                 element will be index. If index = 1 this inserts at the start of the list. If index
  397.                 = fSize + 1 this inserts at the end of the list. Signals Failure if unable to
  398.                 increase the size of the list.}
  399.  
  400.                 PROCEDURE TList.InsertFirst(item: TObject);
  401.                 { Insert a reference to item at the front of the list. If the compile-flag qDebug is
  402.                 TRUE & SetEltType was called, verify item's type. Increase fSize by 1. The index of
  403.                 the new element will be 1. Signals Failure if unable to increase the size of the
  404.                 list.}
  405.  
  406.                 PROCEDURE TList.InsertLast(item: TObject);
  407.                 { Insert a reference to item at the back of the list. If the compile-flag qDebug is
  408.                 TRUE & SetEltType was called, verify item's type. Increase fSize by 1. The index of
  409.                 the new element will be fSize. Signals Failure if unable to increase the size of
  410.                 the list.}
  411.  
  412.                 {Item Deletion Methods}
  413.  
  414.                 PROCEDURE TList.AtDelete(index: ArrayIndex);
  415.                 { Deletes via an index (rather than having to search for an item) }
  416.  
  417.                 PROCEDURE TList.Delete(item: TObject);
  418.                 { Delete the first reference to item from the list, but do not free item. If item
  419.                 does not occur, do nothing. If item does occur, reduce fSize by 1.
  420.  
  421.                 !!! NOTE: This name conflicts with the Pascal builtin: DELETE and we will be
  422.                 changing it's name, but changing the name at the _last minute_ isn't a good idea.
  423.                 If you need to use the builtin DELETE in a TList subclass, then you will have to
  424.                 create a wrapper procedure that forwards to it, for now. Sorry… the Management. }
  425.  
  426.                 PROCEDURE TList.DeleteAll;
  427.                { Delete every element from the list, but do not free any objects. Leave fSize at 0.}
  428.  
  429.                 PROCEDURE TList.FreeAll;
  430.                 { Frees each element in the list.  Leave fSize at 0.}
  431.  
  432.                 { Misc. functions }
  433.  
  434.                 PROCEDURE TList.SortBy(FUNCTION
  435.                                              CompareItems(item1, item2: TObject): CompareResult);
  436.                 { Sorts the list using the supplied CompareItems function.   Uses Shell sort (see
  437.                 Sedgewick, "Algorithms", pp. 97-9)  }
  438.  
  439.                 PROCEDURE TList.Push(item: TObject);
  440.                 { LIFO stack push.(same as insertLast) }
  441.  
  442.                 FUNCTION TList.Pop: TObject;
  443.                 { LIFO stack pop. }
  444.  
  445.                 { Debugging Methods }
  446.  
  447.                 PROCEDURE TList.SetEltType(toClass: MAName);
  448.                 { Call this once and pass the className of objects you intend to insert into the
  449.                 list. The TList insert methods will do a coercion to he type you specify, to ensure
  450.                 that the list contains only elements of the right type.}
  451.  
  452.                 PROCEDURE TList.SetEltTypeID(toClassID: ObjClassID);
  453.                 { Call this once and pass the ObjClassID of objects you intend to insert into the
  454.                 list. The TList insert methods will do a coercion to the type you specify, to
  455.                 ensure that the list contains only elements of the right type.}
  456.  
  457.                 PROCEDURE TList.Fields(PROCEDURE DoToField(fieldName: Str255;
  458.                                                            fieldAddr: Ptr;
  459.                                                            fieldType: integer)); OVERRIDE;
  460.                 { Used by the Inspector and the Debugger to display the contents of this class's
  461.                 fields. }
  462.  
  463.                 PROCEDURE TList.DynamicFields(PROCEDURE
  464.                                               DoToField(fieldName: Str255;
  465.                                                         fieldAddr: Ptr;
  466.                                                         fieldType: integer)); OVERRIDE;
  467.                 { Used by the Inspector and the Debugger to display the contents of this class's
  468.                 dynamic area. }
  469.                 PROCEDURE TList.GetInspectorName(VAR inspectorName: Str255); OVERRIDE;
  470.                 { Used by the Inspector to display the name of this class. }
  471.  
  472.                 END;
  473.  
  474.             TSortedList         = OBJECT (TList)        { A sorted list of TObjects. Items are
  475.                                                          sorted based on the results of Compare
  476.                                                          which has to be overridden to provide a
  477.                                                          comparison mechanism. }
  478.                 PROCEDURE TSortedList.ISortedList;
  479.                 { Initialize a sorted list }
  480.  
  481.                 FUNCTION TSortedList.DoSearch(FUNCTION
  482.                                               TestItem(anItem: TObject): CompareResult;
  483.                                               VAR index: ArrayIndex): TObject;
  484.                 { Searches the sorted list until TestItem returns zero or there are no more
  485.                   items to search.    A binary search is used. }
  486.  
  487.                 FUNCTION TSortedList.GetEqualItemNo(item: TObject): ArrayIndex; OVERRIDE;
  488.                 { Return the index of any item that is considered to be equal to the parameter
  489.                 'item'. Two items are considered equal if comparing them with the Compare method
  490.                 returns zero. You may wish to use the constants kItemGreaterThanCriteria,
  491.                 kItemEqualCriteria, kItemLessThanCriteria. }
  492.  
  493.                 PROCEDURE TSortedList.Insert(item: TObject); OVERRIDE;
  494.                 { Inserts the given item into the list in sorted order, using the Compare
  495.                   method to determine the item's location relative to other items in the list. }
  496.  
  497.                 FUNCTION TSortedList.Compare(item1, item2: TObject): CompareResult;
  498.                 { This method compares two items in the list. A negative result indicates that item1
  499.                 < item2. A result of zero indicates that item1 = item2. A positive result indicates
  500.                 that item1 > item2. You may wish to use the constants kItem1LessThanItem2,
  501.                 kItem1EqualItem2, kItem1GreaterThanItem2. By default just compare the ordinal value
  502.                 of the items. Subclasses that want to should override this method to do any other
  503.                 kind of comparison (comparing instance variables, for instance (get it?)). }
  504.  
  505.                 FUNCTION TSortedList.Search(FUNCTION
  506.                                             TestItem(anItem: TObject): CompareResult): TObject;
  507.                 { This method searches the list of an item that causes your supplied TestItem
  508.                 function to return true. This is useful for cases in which you are not comparing
  509.                 objects in the list with another object, as does Compare. For example, suppose each
  510.                 object has an fTitle field and the objects are inserted into the list in order of
  511.                 fTitle. You can use the search method to look for an object whose fTitle is equal
  512.                 to any string. A negative TestItem result indicates that your search criteria <
  513.                 anItem, a result of zero indicates the item has been found and Search returns that
  514.                 item. A positive TestItem result indicates that your search criteria > your anItem.
  515.                 }
  516.  
  517.                 PROCEDURE TSortedList.Sort;
  518.                 { Sorts the list using TSortedList.Compare function and TList.SortBy.}
  519.  
  520.                 PROCEDURE TSortedList.Fields(PROCEDURE DoToField(fieldName: Str255;
  521.                                                            fieldAddr: Ptr;
  522.                                                            fieldType: integer)); OVERRIDE;
  523.                 { Used by the Inspector and the Debugger to display the contents of this class's
  524.                 fields. }
  525.  
  526.                 END;
  527.  
  528.         FUNCTION NewList: TList;
  529.         { A convenience function. Create a TList, initialize it, and return a reference to it.
  530.         Signals Failure if it cannot allocate the object.}
  531.  
  532.         FUNCTION NewSortedList: TSortedList;
  533.         { A convenience function. Create a TSortedList, initialize it, and return a reference to it.
  534.         Signals Failure if it cannot allocate the object.}
  535.  
  536.         FUNCTION NewAllocatedList(iSize: ArrayIndex): TList;
  537.         { A convenience function. The same as NewList, but the initial allocation size can be set. }
  538.  
  539.         FUNCTION FreeListIfObject(list: TList): TList;
  540.         { A convenience function. if list is non-nil then the same as list.FreeList.
  541.         Returns NIL for convenient assignment back to the reference passed in. }
  542.  
  543.         {$ENDC}
  544.  
  545.         {$IFC NOT UsingIncludes}
  546. END.
  547. {$ENDC}
  548.